using System;
using System.Collections.Generic;
using System.Text;
using System.Data.Common;
using System.ComponentModel;
using System.Collections;
using ResourceBlender.Core;

namespace ResourceBlender.Express {
    /// <summary>
    /// Represents an application in ResourceBlender
    /// </summary>
    public class ObservableApplication : RBApplication, INotifyPropertyChanged, IComparable {
        private ObservableSortedDictionary<string, string> bundles;

        /// <summary>
        /// Gets or sets the bundles included in the application. &lt;BundleID, Name&gt;
        /// </summary>
        /// <value>The bundles.</value>
        public new ObservableSortedDictionary<string, string> Bundles {
            get { return bundles; }
            set {
                bundles = value;
                OnPropertyChanged("Bundles");
            }
        }

        /// <summary>
        /// Initializes a new <see cref="ObservableApplication"/>.
        /// </summary>
        public ObservableApplication() 
            : base() {
            this.bundles = new ObservableSortedDictionary<string, string>(new Comparers.DictionaryValueComparer(), new Comparers.StringEqualityComparer());
        }

        /// <summary>
        /// Initializes a new <see cref="ObservableApplication"/>.
        /// </summary>
        public ObservableApplication(string displayName)
            :base (displayName)  {
            this.bundles = new ObservableSortedDictionary<string, string>(new Comparers.DictionaryValueComparer(), new Comparers.StringEqualityComparer());
        }

        /// <summary>
        /// Initializes a new <see cref="ObservableApplication"/>.
        /// </summary>
        /// <param name="reader">The reader.</param>
        public ObservableApplication(DbDataReader reader) 
            : base(reader) {
            this.Bundles = new ObservableSortedDictionary<string, string>(new Comparers.DictionaryValueComparer(), new Comparers.StringEqualityComparer());
        }

        /// <summary>
        /// Initializes a new <see cref="ObservableApplication"/>.
        /// </summary>
        public ObservableApplication(RBApplication app)
            : base() {
            this.applicationName = app.ApplicationName;
            this.defaultLanguage = app.DefaultLanguage;
            this.displayName = app.DisplayName;
            this.id = app.ID;
            this.languages = app.Languages;
            //this.bundles = new ObservableSortedDictionary<string, string>(new Comparers.DictionaryValueComparer(), app.Bundles, new Comparers.StringEqualityComparer());
            this.bundles = new ObservableSortedDictionary<string, string>(new Comparers.DictionaryValueComparer(), new Comparers.StringEqualityComparer());
            foreach(var bundle in app.Bundles) {
                bundles.Add(bundle.Key, bundle.Value);
            }
        }

        /// <summary>
        /// Creates a deep copy of this instance.
        /// </summary>
        /// <returns></returns>
        public ObservableApplication Clone() {
            ObservableApplication clone = new ObservableApplication();
            clone.ID = this.ID;
            clone.ApplicationName = this.ApplicationName;
            clone.DisplayName = this.DisplayName;
            clone.DefaultLanguage = this.DefaultLanguage;
            clone.Languages = this.Languages;
            clone.Bundles = this.Bundles;
            return clone;
        }

        /// <summary>
        /// Compares this ObservableApplication to another one by name.
        /// </summary>
        /// <param name="obj">An object to compare with this instance.</param>
        /// <returns>
        /// </returns>
        /// <exception cref="T:System.ArgumentException">
        /// 	<paramref name="obj"/> is not the same type as this instance.
        /// </exception>
        public int CompareTo(object obj) {
            if(obj == null || !(obj is ObservableApplication)) {
                return 1;
            } else {
                return this.DisplayName.CompareTo((obj as ObservableApplication).DisplayName);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string strPropertyName) {
            if(PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs(strPropertyName));
            }
        }
    }    
}
